package com.file.manage.domain.service.impl;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.file.manage.domain.data.OperationLogsVO;
import com.file.manage.domain.data.UserFileMappingVO;
import com.file.manage.domain.entity.File;
import com.file.manage.domain.entity.OperationLogs;
import com.file.manage.domain.entity.User;
import com.file.manage.domain.entity.UserFileMapping;
import com.file.manage.domain.entity.convertor.OperationLogsConvertor;
import com.file.manage.domain.entity.convertor.UserFileMappingConvertor;
import com.file.manage.domain.enums.OperationType;
import com.file.manage.domain.param.OperationLogsQueryParam;
import com.file.manage.domain.service.OperationLogsService;
import com.file.manage.domain.service.UserFileMappingService;
import com.file.manage.infrastructure.base.Pager;
import com.file.manage.infrastructure.base.dto.query.PageQuery;
import com.file.manage.infrastructure.base.service.impl.BaseServiceImpl;
import com.file.manage.infrastructure.config.CurrentUserCache;
import com.file.manage.infrastructure.dao.FileDao;
import com.file.manage.infrastructure.dao.UserDao;
import com.file.manage.infrastructure.dao.impl.OperationLogsDaoImpl;
import com.file.manage.infrastructure.dao.impl.UserFileMappingImpl;
import com.file.manage.infrastructure.utils.ConvertUtil;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author H41
 * @Type OperationLogsServiceImpl.java
 * @date 2025/5/31 12:31
 * @Desc
 */
@Service
public class UserFileMappingServiceImpl extends BaseServiceImpl<UserFileMappingImpl, UserFileMapping> implements UserFileMappingService {

    @Resource
    private UserDao userDao;
    @Resource
    private FileDao fileDao;

    @Override
    public List<UserFileMappingVO> listByFileId(String fileId) {
        List<UserFileMapping> list = baseDao.selectByFileId(fileId);
        return dataProcessing(list);
    }

    @Override
    public List<UserFileMappingVO> listByUserId(String userId) {
        List<UserFileMapping> list = baseDao.selectByUserId(userId);
        return dataProcessing(list);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(String userId, List<String> fileIds) {
        baseDao.deleteByUserId(userId);

        List<UserFileMapping> userFileMappings = new ArrayList<>();
        for (String fileId : fileIds) {
            UserFileMapping userFileMapping = new UserFileMapping();
            userFileMapping.setUserId(userId);
            userFileMapping.setFileId(fileId);
            userFileMappings.add(userFileMapping);
        }
        baseDao.saveBatch(userFileMappings);
    }

    private List<UserFileMappingVO> dataProcessing(List<UserFileMapping> list) {
        List<UserFileMappingVO> result = new ArrayList<>();
        if (CollUtil.isNotEmpty(list)) {
            List<String> userIds = list.stream().map(UserFileMapping::getUserId).collect(Collectors.toList());
            Map<String, User> userMap = userDao.mapByIds(userIds);
            List<String> fileIds = list.stream().map(UserFileMapping::getFileId).collect(Collectors.toList());
            Map<String, File> fileMap = ConvertUtil.getMap(fileDao.listByIds(fileIds));

            for (UserFileMapping userFileMapping : list) {
                result.add(UserFileMappingConvertor.INSTANCE.toUserFileMappingVO(userFileMapping,
                        userMap.get(userFileMapping.getUserId()) != null ? userMap.get(userFileMapping.getUserId()).getName() : null,
                        fileMap.get(userFileMapping.getFileId()) != null ? fileMap.get(userFileMapping.getFileId()).getName() : null)
                );
            }
        }
        return result;
    }
}
